/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "StdAfx.h"
#include "AABoundingBox.h"
#include "BoundingSphere.h"

namespace model {

AABoundingBox::AABoundingBox(void)
:	m_bIsNull(true),
	m_vMin(99999,99999,99999),
	m_vMax(-99999, -99999, -99999)
{
}

AABoundingBox::AABoundingBox(const math::Vector3 &min, const math::Vector3 &max)
:	m_vMin(min), 
	m_vMax(max), 
	m_bIsNull(false)
{
}

AABoundingBox::~AABoundingBox(void)
{
}

const math::Vector3& AABoundingBox::getMin() const
{
	return m_vMin;
}

const math::Vector3& AABoundingBox::getMax() const
{
	return m_vMax;
}

void AABoundingBox::setMin(const math::Vector3 &min)
{
	m_vMin = min;
	m_bIsNull = false;
}

void AABoundingBox::setMax(const math::Vector3 &max)
{
	m_vMax = max;
	m_bIsNull = false;
}

void AABoundingBox::setSize(const math::Vector3 &min, const math::Vector3 &max)
{
	m_vMin = min;
	m_vMax = max;
	m_bIsNull = false;
}

void AABoundingBox::combine(const AABoundingBox &aab)
{
	// Do nothing, if the other box is null
	if (aab.m_bIsNull)
		return;

	// Set this the the other box, if this is null
	if (m_bIsNull) { 
		setSize(aab.getMin(), aab.getMax());
		return;
	}

	// Merge the boxes
	setSize( m_vMin.floor( aab.getMin() ), m_vMax.ceil( aab.getMax() ) );
}

math::Vector3 AABoundingBox::getCenter() const
{
	return (m_vMax - m_vMin)/2.0f;
}

bool AABoundingBox::isIntersecting(const BoundingSphere &sphere)
{
    float s, d = 0;
	math::Vector3 C = sphere.getCenter();

    //find the square of the distance
    //from the sphere to the box
    for( long i=0 ; i<3 ; ++i ) {
		if( C[i] < m_vMin[i] )
        {
            s = C[i] - m_vMin[i];
            d += s*s;
        }
		else if( C[i] > m_vMax[i] )
        {

            s = C[i] - m_vMax[i];
            d += s*s; 

        }

    }
	return d <= sphere.getRadius()*sphere.getRadius();

}

} // namespace
